package com.qumitech.visualnovel.controller.rest;

import com.alibaba.fastjson.JSONObject;
import com.qumitech.visualnovel.component.util.CommonUtil;
import com.qumitech.visualnovel.console.excel.ExportExcel;
import com.qumitech.visualnovel.model.common.BaseRsp;
import com.qumitech.visualnovel.model.common.ResultEnum;
import com.qumitech.visualnovel.model.common.BaseResponse;
import com.qumitech.visualnovel.model.dao.app.Account;
import com.qumitech.visualnovel.model.dao.console.AccountGroupConfig;
import com.qumitech.visualnovel.pubdef.dto.realinfo.UserRealInfoAdminUpdateDTO;
import com.qumitech.visualnovel.pubdef.dto.user.AccountBindDTO;
import com.qumitech.visualnovel.service.account.AccountGroupService;
import com.qumitech.visualnovel.service.account.AccountService;
import com.google.common.collect.ImmutableMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

/**
 * AccountController
 *
 * @author ywxie
 * @date 2020/1/10 17:56
 */
@RestController
@RequestMapping("/api/account")
public class AccountController {

    @Autowired
    private AccountService accountService;

    @Autowired
    private AccountGroupService groupService;

    @GetMapping("/realinfo")
    public BaseRsp listUserRealInfoAdmin(@RequestParam(value = "limit", required = false, defaultValue = "20") String limit,
                                         @RequestParam(value = "offset", required = false, defaultValue = "0") String offset,
                                         @RequestParam(value = "uid", required = false) String uid,
                                         @RequestParam(value = "state", required = false) String state,
                                         @RequestParam(value = "startTime", required = false) String startTime,
                                         @RequestParam(value = "endTime", required = false) String endTime){
        Map<String, String> paramMap = new HashMap<>(16);
        paramMap.put("limit", limit);
        paramMap.put("offset", offset);
        if(uid != null){
            paramMap.put("uid", uid);
        }
        if(state != null){
            paramMap.put("state", state);
        }
        if(startTime != null){
            paramMap.put("start_time", startTime);
        }
        if(endTime != null){
            paramMap.put("end_time", endTime);
        }
        return accountService.listUserRealInfoAdmin(paramMap);
    }

    @PutMapping("/realinfo")
    public BaseRsp updateUserRealInfoAdmin(@RequestBody UserRealInfoAdminUpdateDTO updateDTO){
        return accountService.updateUserRealInfoAdmin(updateDTO);
    }

    @RequestMapping(value = "/groupconfig", method = RequestMethod.GET)
    public JSONObject getGroupConfig(){
        List<HashMap<String,Object>> list = groupService.getAccountGroups();
        JSONObject result = new JSONObject();
        result.put("items", list);
        return new BaseResponse<>(result);
    }

    @GetMapping("/groupinfo")
    public BaseRsp listGroupInfo(@RequestParam(value = "pageSize", required = false, defaultValue = "20") Integer pageSize,
                                 @RequestParam(value = "offset", required = false, defaultValue = "0") Integer offset,
                                 @RequestParam(value = "levelId", required = false) Integer levelId,
                                 @RequestParam(value = "startTime", required = false) String startTime,
                                 @RequestParam(value = "endTime", required = false) String endTime) {
        return new BaseRsp(ResultEnum.SUCCESS,  ImmutableMap.of("account_info_data",
                groupService.listAccountGroupInfoData(levelId, startTime, endTime, offset, pageSize),
                "count", groupService.getCount(levelId, startTime, endTime)));
    }

    @RequestMapping(value="/download", method = RequestMethod.GET)
    public void download(HttpServletResponse response, @RequestParam(value="id") Long id) {
        AccountGroupConfig groupConfig = groupService.findGroupConfigById(id);
        String filePath = groupConfig.getDownload();
        String suffix = filePath.substring(filePath.lastIndexOf("/") + 1);
        response.setContentType("application/octet-stream;charset=UTF-8");
        try {
            response.setHeader("Content-disposition",
                    "attachment;filename=" + URLEncoder.encode(suffix, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try {
            CommonUtil.getDownload(response, filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping(value = "/excel", method = RequestMethod.POST)
    public BaseRsp importExcel(@RequestParam("file") MultipartFile file) {
        List<String> userIds = accountService.importUser(file);
        return new BaseRsp(ResultEnum.SUCCESS, userIds);
    }

    @RequestMapping(value = "/uidsList", method = RequestMethod.POST)
    public BaseRsp getUserList(@RequestBody JSONObject param) {
        String[] uidArray = ((String) param.get("uids")).split(",");
        List<String> uidList = Arrays.asList(uidArray);
        return new BaseRsp(ResultEnum.SUCCESS, getUserIds(uidList));
    }

    @RequestMapping(value = "/userIds/export", method = RequestMethod.POST)
    public BaseRsp exportUserIds(@RequestBody JSONObject param, HttpServletResponse request) {
        String[] uidArray = ((String) param.get("uids")).split(",");
        List<String> uidList = Arrays.asList(uidArray);
        accountService.exportUserIds(request, uidList);
        return new BaseRsp(ResultEnum.SUCCESS);
    }

    private JSONObject getUserIds(List<String> uidList) {
        JSONObject map = new JSONObject();
        List<JSONObject> userList = new ArrayList<>(16);
        Map<String, String> ids = new HashMap<>(16);
        // 根据内部ID查询
        List<Account> accounts = accountService.getList(uidList);
        if (accounts.size() > 0) {
            for (Account account: accounts) {
                ids.put(account.getUid().toString(), account.getPresentId());
            }
        } else {
            // 根据外部ID查询
            accounts = accountService.getPresentList(uidList);
            for (Account account: accounts) {
                ids.put(account.getPresentId(), account.getUid().toString());
            }
        }

        for (String uid: uidList) {
            JSONObject obj = new JSONObject();
            obj.put(uid, ids.get(uid));
            userList.add(obj);
        }

        map.put("uidList", userList);
        return map;
    }

    @GetMapping("/groupinfo/active")
    @ExportExcel(itemKeys = {"uid","presentId","userName","lastActiveTime","registerTime","firstOrderTime","verifyTime","targetDate"},
            itemNames = {"内部ID","显示ID","昵称","最后活跃时间","注册时间","首次充值时间","认证大神时间","统计日期"},
            listKey = "account_active_data")
    public BaseRsp listGroupActiveInfo(@RequestParam(value = "limit", required = false, defaultValue = "20") Integer pageSize,
                                 @RequestParam(value = "offset", required = false, defaultValue = "0") Integer offset,
                                 @RequestParam(value = "groupId", required = false) Integer groupId,
                                 @RequestParam(value = "startTime", required = false) String startTime,
                                 @RequestParam(value = "endTime", required = false) String endTime) {
        return new BaseRsp(ResultEnum.SUCCESS,  ImmutableMap.of("account_active_data",
                groupService.listAccountDailyActive(groupId, startTime, endTime, offset, pageSize),
                "count", groupService.getAccountActiveCount(groupId, startTime, endTime)));
    }

    @RequestMapping(value = "/groupinfo/active/export", method = RequestMethod.POST)
    public BaseRsp listGroupActiveInfoExport(@RequestParam(value = "pageSize", required = false, defaultValue = "20") Integer pageSize,
                                             @RequestParam(value = "offset", required = false, defaultValue = "0") Integer offset,
                                             @RequestParam(value = "groupId", required = false) Integer groupId,
                                             @RequestParam(value = "startTime", required = false) String startTime,
                                             @RequestParam(value = "endTime", required = false) String endTime,
                                             HttpServletResponse response) {
        groupService.listGroupActiveInfoExport(groupId, startTime, endTime, offset, pageSize, response);
        return new BaseRsp(ResultEnum.SUCCESS);
    }


    @RequestMapping(value = "/admin/bind", method = RequestMethod.PUT)
    public BaseRsp bindOldAccount(@RequestBody AccountBindDTO bindDTO) {
        accountService.bindOldAccount(bindDTO);
        return new BaseRsp(ResultEnum.SUCCESS);
    }
}
